package com.lxyk.service.user.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lxyk.dao.user.UserInfoDao;
import com.lxyk.domain.PageBean;
import com.lxyk.dao.user.UserDao;
import com.lxyk.domain.SysRole;
import com.lxyk.domain.SysUser;
import com.lxyk.domain.UserInfo;
import com.lxyk.service.user.RoleService;
import com.lxyk.service.user.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private RoleService roleService;

    //加密对象
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    //添加用户
    @Override
    public boolean save(SysUser user, UserInfo userInfo) {
        //判断该用户名是否重复
        SysUser byName = userDao.findByName(user.getUsername());
        //不重复再插入
        if(byName == null){
            //保存用户
            //密码加密
            user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
            userDao.save(user);
            //保存用户详情
            userInfo.setUid(user.getId());
            userInfoDao.save(userInfo);
            return true;
        }
        //用户名重复
        return false;
    }

    //查询所有用户
    @Override
    public PageBean findAll(Integer page, Integer size) {
        //当前页数,从0开始; 每页条数
        PageHelper.startPage(page,size);
        List<SysUser> list = userDao.findAll();
        PageInfo pageInfo = new PageInfo<>(list);
        PageBean<SysUser> pageBean = new PageBean<>(pageInfo,list);
        return pageBean;
    }

    //查询所有角色信息和该用户所属角色id集合(用于修改之前的展示)
    @Override
    public Map<String, Object> toAddRolePage(Integer id) {
        //查询所有角色
        List<SysRole> allRoles = roleService.findAll();
        //根据用户id查询出所有对应角色的id
        List<Integer> myRoles = userDao.findRolesByUid(id);
        //封装数据(所有角色,该用户的所有角色id)
        Map<String, Object> map = new HashMap<>();
        map.put("allRoles", allRoles);
        map.put("myRoles", myRoles);
        return map;
    }

    //修改用户的角色(先清空, 再往用户角色表中插入数据)
    @Override
    public void addRoleToUser(Integer userId, Integer[] ids) {
        //先根据用户id删除用户角色表中对应的数据
        userDao.removeRoles(userId);
        //重新建立该用户与角色之间的关系(往用户角色表中插入数据)
        for (Integer rid : ids) {
            userDao.addRoles(userId, rid);
        }
    }

    @Override
    public Integer delete(Integer id) {
        return userDao.delete(id);
    }

    //根据用户名查询用户信息,用户详情,角色信息
    @Override
    public SysUser findByName(String username) {
        //查询用户信息,角色详情
        SysUser sysUser = userDao.findByName(username);
        //根据用户id查询用户详情
        UserInfo userInfo = userInfoDao.findByUid(sysUser.getId());
        sysUser.setUserInfo(userInfo);
        return sysUser;
    }

    //更新数据 user和userInfo
    @Override
    public boolean update(SysUser user) {
        //密码加密
        if(user.getPassword().length()<=20){
            user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        }
        Integer i = userDao.update(user);
        Integer j = userInfoDao.update(user.getUserInfo());
        return i==1 && j==1;
    }

    @Override
    public void editPassword(SysUser user) {
        //加密
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        userDao.editPassword(user);
    }

    /**
     * 认证业务
     * @param username 用户在浏览器输入的用户名
     * @return UserDetails是security自己的用户对象
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try {
            //1.根据用户名去数据库查询出用户信息以及角色列表信息
            SysUser sysUser = userDao.findByName(username);
            if(sysUser == null){
                //返回null就是认证失败
                return null;
            }
            //2.将用户的角色列表赋值给认证对象
            //创建集合用于存储角色信息,一个SimpleGrantedAuthority对应一个角色
            List<SimpleGrantedAuthority> list = new ArrayList<>();
            //遍历角色列表
            for (SysRole role : sysUser.getRoles()) {
                //根据角色名称创建SimpleGrantedAuthority对象
                SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(role.getRoleName());
                //将对象添加到集合
                list.add(simpleGrantedAuthority);
            }

            //3.创建UserDetails对象,传入用户名,密码,角色列表
            //加上用户状态认证  status为1才代表可用
            UserDetails userDetails = new User(sysUser.getUsername(),
                    sysUser.getPassword(),
                    sysUser.getStatus()==1,
                    true,
                    true,
                    true,
                    list);
            return userDetails;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
